package com.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reggie.common.ReggieContext;
import com.reggie.dto.OrdersDto;
import com.reggie.entity.*;
import com.reggie.exception.CustomException;
import com.reggie.mapper.OrderMapper;
import com.reggie.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements OrderService {
    @Autowired
    private AddressBookService addressBookService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private UserService userService;
    @Autowired
    private DishService dishService;
    @Autowired
    private SetmealService setmealService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitOrder(Orders orders) {
        Long userPhone = ReggieContext.get();
        User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getPhone, userPhone));
        List<ShoppingCart> shoppingCarts = shoppingCartService.list(new LambdaQueryWrapper<ShoppingCart>().eq(ShoppingCart::getUserId, userPhone));
        if (shoppingCarts == null || shoppingCarts.size() < 1)
            throw new CustomException("购物车为空,请刷新后重试");
        Long addressBookId = orders.getAddressBookId();
        AddressBook addressBook = addressBookService.getById(addressBookId);
        if (addressBook == null)
            throw new CustomException("地址信息有误");
        orders.setAddress(addressBook.getDetail());
        orders.setStatus(2);
        orders.setUserId(userPhone);
        orders.setOrderTime(LocalDateTime.now());
        orders.setCheckoutTime(LocalDateTime.now());
        AtomicInteger atomicInteger = new AtomicInteger(0);
        List<OrderDetail> orderDetails = new ArrayList<>();
        shoppingCarts.forEach(shoppingCart -> {
            atomicInteger.addAndGet(shoppingCart.getNumber() * shoppingCart.getAmount().multiply(new BigDecimal(100)).intValue());
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(shoppingCart, orderDetail, "id", "userId", "createTime");
            orderDetails.add(orderDetail);

        });
        orders.setAmount(new BigDecimal(String.valueOf(atomicInteger)).divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP));
        orders.setUserName(user.getName());
        long id = IdWorker.getId();
        orders.setNumber(String.valueOf(id));
        orders.setPhone(addressBook.getPhone());
        orders.setConsignee(addressBook.getConsignee());
        this.save(orders);
        orderDetails.forEach(orderDetail -> orderDetail.setOrderId(orders.getId()));
        orderDetailService.saveBatch(orderDetails);
        shoppingCartService.remove(new LambdaQueryWrapper<ShoppingCart>().eq(ShoppingCart::getUserId, userPhone));

    }

    @Override
    public Page<OrdersDto> userPage(Integer page, Integer pageSize) {
        Page<Orders> ordersPage = new Page<>(page, pageSize);
        this.page(ordersPage, new LambdaQueryWrapper<Orders>().eq(Orders::getUserId, ReggieContext.get()).orderByDesc(Orders::getCheckoutTime));
        List<Orders> records = ordersPage.getRecords();
        if (records==null||records.size()<1)
            throw new CustomException("暂无订单");
        Page<OrdersDto> ordersDtoPage = new Page<>();
        List<OrdersDto> ordersDtos = new ArrayList<>();
        Set<Long> orderIds = new HashSet<>();
        records.forEach(rec -> orderIds.add(rec.getId()));
        List<OrderDetail> orderDetails = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>().in(OrderDetail::getOrderId, orderIds));
        BeanUtils.copyProperties(ordersPage, ordersDtoPage, "records");
        records.forEach(record -> {
            OrdersDto ordersDto = new OrdersDto();
            BeanUtils.copyProperties(record, ordersDto);
            ordersDto.setOrderDetails(new ArrayList<>());
            orderDetails.forEach(orderDetail -> {
                if (orderDetail.getOrderId().equals(record.getId()))
                    ordersDto.getOrderDetails().add(orderDetail);
            });
            ordersDtos.add(ordersDto);
        });
        ordersDtoPage.setRecords(ordersDtos);
        return ordersDtoPage;
    }

    @Override
    public Page<OrdersDto> pageOrdersDto(Integer page, Integer pageSize, Long number, LocalDateTime beginTime, LocalDateTime endTime) {
        Page<Orders> ordersPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<Orders> ordersLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ordersLambdaQueryWrapper.eq(number != null, Orders::getNumber, number);
        ordersLambdaQueryWrapper.gt(beginTime != null, Orders::getOrderTime, beginTime);
        ordersLambdaQueryWrapper.lt(endTime != null, Orders::getOrderTime, endTime);
        this.page(ordersPage, ordersLambdaQueryWrapper);
        Page<OrdersDto> ordersDtoPage = new Page<>();
        BeanUtils.copyProperties(ordersPage, ordersDtoPage, "records");
        List<Orders> records = ordersPage.getRecords();
        if(records==null||records.size()<1)
            throw new CustomException("订单为空");
        Set<Long> orderIds = new HashSet<>();
        records.forEach(rec -> orderIds.add(rec.getId()));
        List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>().in(OrderDetail::getOrderId, orderIds));
        List<OrdersDto> ordersDtos = new ArrayList<>();
        records.forEach(rec -> {
            OrdersDto ordersDto = new OrdersDto();
            ordersDto.setOrderDetails(new ArrayList<>());
            BeanUtils.copyProperties(rec, ordersDto);
            orderDetailList.forEach(orderDetail -> {
                if (orderDetail.getOrderId().equals(rec.getId()))
                    ordersDto.getOrderDetails().add(orderDetail);
            });
            ordersDtos.add(ordersDto);
        });
        ordersDtoPage.setRecords(ordersDtos);
        return ordersDtoPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void againOrder(Long id) {
        //先将这个订单的订单详情查出来
        LambdaQueryWrapper<OrderDetail> orderDetailLambdaQueryWrapper = new LambdaQueryWrapper<>();
        orderDetailLambdaQueryWrapper.eq(OrderDetail::getOrderId,id);
        List<OrderDetail> orderDetailList = orderDetailService.list(orderDetailLambdaQueryWrapper);
        List<OrderDetail> newOrderDetailList=new ArrayList<>();
        List<Long> dishIds=new ArrayList<>();
        List<Long> mealIds=new ArrayList<>();
        //将订单详情里的菜品id和套餐id取出来
        orderDetailList.forEach(orderDetail ->{
            if (orderDetail.getDishId()!=null)
                dishIds.add(orderDetail.getDishId());
            if (orderDetail.getSetmealId()!=null)
                mealIds.add(orderDetail.getSetmealId());
        } );
        //如果套餐id列表有数据
        if (mealIds!=null&&mealIds.size()>0){
            LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
            setmealLambdaQueryWrapper.in(Setmeal::getId,mealIds);
            setmealLambdaQueryWrapper.eq(Setmeal::getStatus,1);
            //根据套餐idList将套餐表中已上架的菜品查出来
            List<Setmeal> setmealList = setmealService.list(setmealLambdaQueryWrapper);
            orderDetailList.forEach(orderDetail -> {
                setmealList.forEach(setmeal -> {
                    //如果套餐还是上架状态，就将这一条订单详情装到新创建的集合中
                    if (setmeal.getId().equals(orderDetail.getSetmealId()))
                        newOrderDetailList.add(orderDetail);
                });
            });
        }
        //同套餐逻辑
        if (dishIds!=null&&dishIds.size()>0){
            LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
            dishLambdaQueryWrapper.in(Dish::getId,dishIds);
            dishLambdaQueryWrapper.eq(Dish::getStatus,1);
            List<Dish> dishList = dishService.list(dishLambdaQueryWrapper);
            orderDetailList.forEach(orderDetail -> {
                dishList.forEach(dish -> {
                    if (dish.getId().equals(orderDetail.getDishId()))
                        newOrderDetailList.add(orderDetail);
                });
            });
        }
        //如果新的订单详情集合是空的，说明这个订单里所有的商品都下架了，直接返回
        if (newOrderDetailList==null||newOrderDetailList.size()<1){
            throw new CustomException("商品已全部下架！");
        }
        LambdaQueryWrapper<ShoppingCart> shoppingCartLambdaQueryWrapper = new LambdaQueryWrapper<>();
        shoppingCartLambdaQueryWrapper.eq(ShoppingCart::getUserId,ReggieContext.get());
        //先将现在用户的购物车信息给清空
        shoppingCartService.remove(shoppingCartLambdaQueryWrapper);
        List<ShoppingCart> shoppingCarts=new ArrayList<>();
        //将订单详情集合中的数据copy到购物车对象中，把购物车对象存到一个集合中
        newOrderDetailList.forEach(orderDetail -> {
            ShoppingCart shoppingCart = new ShoppingCart();
            BeanUtils.copyProperties(orderDetail,shoppingCart,"id","orderId");
            shoppingCart.setUserId(ReggieContext.get());
            shoppingCarts.add(shoppingCart);
        });
        //再将新的购物车信息添加到数据库
        shoppingCartService.saveBatch(shoppingCarts);
    }


}
